using Godot;
using System;

// 定义颜色枚举（建议放在一个全局工具类里，或者单独文件，这里先写在一起）
public enum BlockColor { Red, Blue, Green, World }


[Tool] // 允许编辑器实时预览
public partial class ChromaBlock : RigidBody2D
{
    // --- 1. 大小与外观控制 ---
    [ExportGroup("Appearance")]
    [Export]
    public Vector2 BlockSize
    {
        get => _blockSize;
        set
        {
            _blockSize = value;
            UpdateSize(); // 修改大小时立即刷新
        }
    }
    private Vector2 _blockSize = new Vector2(64, 64);

    // --- 2. 颜色控制 ---
    [ExportGroup("Gameplay")]
    [Export]
    public BlockColor ColorType
    {
        get => _colorType;
        set
        {
            _colorType = value;
            UpdateState(); // 修改颜色时刷新物理层
        }
    }
    private BlockColor _colorType = BlockColor.Red;

    // --- 3. 物理行为控制 ---
    [Export]
    public bool IsPushable
    {
        get => _isPushable;
        set
        {
            _isPushable = value;
            UpdateState(); // 修改状态时刷新冻结模式
        }
    }
    private bool _isPushable = false;

    // --- 内部引用 ---
    [Export] public Sprite2D VisualSprite;
    [Export] public CollisionShape2D Collider;

    // 物理层常量 (对应 Project Settings)
    private const int LAYER_WORLD = 1;
    private const int LAYER_RED = 2;
    private const int LAYER_BLUE = 3;

    private const int LAYER_GREEN = 4;

    public override void _Ready()
    {
        UpdateSize();
        UpdateState();
    }

    // 更新大小 (纹理平铺 + 碰撞体调整)
    private void UpdateSize()
    {
        if (VisualSprite != null)
        {
            // 关键：不改变Scale，而是改变显示区域 (RegionRect)
            // 这样纹理就会平铺，而不是拉伸
            VisualSprite.RegionRect = new Rect2(Vector2.Zero, _blockSize);

            // 居中显示 Sprite (因为 Region 是从左上角开始画的，我们需要稍微偏移一下让它对齐中心)
            // 或者更简单的：Sprite2D 默认就是 Centered=true，RegionRect 会以中心扩展吗？
            // 实测：RegionRect 的偏移需要配合 Sprite 的 Offset 或 Position 调整。
            // 最稳妥的做法：Sprite 保持 Centered=true，Region 正常设。
        }

        if (Collider != null)
        {
            // 确保形状资源独立
            if (Collider.Shape == null || !Collider.Shape.IsLocalToScene())
            {
                Collider.Shape = new RectangleShape2D();
            }

            if (Collider.Shape is RectangleShape2D rect)
            {
                rect.Size = _blockSize;
            }
        }
    }

    // 更新状态 (颜色 + 物理冻结)
    private void UpdateState()
    {
        // 1. 处理推拉逻辑 (RigidBody 冻结)
        if (_isPushable)
        {
            Freeze = false; // 解冻，受重力，可推动
            // 确保它可以与世界碰撞 (否则会掉出地图)
            CollisionMask = 1; // 至少包含 World (Layer 1)
            CollisionLayer = 0; // 先清空，后面根据颜色设置

        }
        else
        {
            Freeze = true;  // 冻结，变成静态墙
            FreezeMode = FreezeModeEnum.Static;
        }

        // 2. 处理颜色与视觉
        Color visualModulate = Colors.White;

        // 重置物理层 (Layer)
        // 自身属于哪一层？
        SetCollisionLayerValue(LAYER_WORLD, false);
        SetCollisionLayerValue(LAYER_RED, false);
        SetCollisionLayerValue(LAYER_BLUE, false);
        SetCollisionLayerValue(LAYER_GREEN, false);

        switch (_colorType)
        {
            case BlockColor.Red:
                visualModulate = Colors.Red;
                SetCollisionLayerValue(LAYER_RED, true);

                break;

            case BlockColor.Blue:
                visualModulate = Colors.Cyan;
                SetCollisionLayerValue(LAYER_BLUE, true);
                break;

            case BlockColor.Green:
                visualModulate = Colors.Lime;
                SetCollisionLayerValue(LAYER_GREEN, true);
                break;

            case BlockColor.World:
                visualModulate = Colors.White;
                SetCollisionLayerValue(LAYER_WORLD, true);
                break;
        }

        uint newMask = 0;

        // 基础：必须撞地板，否则掉出世界
        newMask |= (1 << (LAYER_WORLD - 1)); // Layer 1

        if (_isPushable)
        {
            if (_colorType == BlockColor.Red)
            {
                // 我是红箱子：撞地板 + 撞红箱子 + 撞红墙
                newMask |= 1 << (LAYER_RED - 1); // Layer 2
            }
            else if (_colorType == BlockColor.Blue)
            {
                // 我是蓝箱子：撞地板 + 撞蓝箱子 + 撞蓝墙
                newMask |= 1 << (LAYER_BLUE - 1); // Layer 3
            }
            else if (_colorType == BlockColor.Green)
            {
                // 我是绿箱子：撞地板 + 撞绿箱子 + 撞绿墙
                newMask |= 1 << (LAYER_GREEN - 1); // Layer 4
            }
            else if (_colorType == BlockColor.World)
            {
                // 普通箱子：撞所有东西
                newMask |= 1 << (LAYER_RED - 1);
                newMask |= 1 << (LAYER_BLUE - 1);
            }
        }
        else
        {
            // 如果不可推 (Freeze=true)，Mask 其实不重要，
            // 因为静态物体通常不主动检测碰撞，而是被别人撞。
            // 但为了安全起见，保持默认即可。
            newMask = 1;
        }

        CollisionMask = newMask;

        if (VisualSprite != null)
        {
            VisualSprite.Modulate = visualModulate;
        }
    }
}